package cn.lxking.business.auth.center.controller;

import cn.lxking.business.auth.center.dto.LoginInfo;
import cn.lxking.business.auth.center.dto.LoginRequest;
import cn.lxking.business.auth.center.dto.RegisterRequest;
import cn.lxking.business.auth.center.service.SysUserService;
import cn.lxking.core.utils.JsonUtil;
import cn.lxking.core.utils.OkHttpClientUtil;
import cn.lxking.core.data.ResponseResult;
import com.google.common.collect.Maps;
import okhttp3.Response;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author ArcherTrister
 */
@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("vue-element-admin")
public class AccountController {
    private static final String URL_OAUTH_TOKEN = "http://localhost:9001/oauth/token";

    @Value("${business.auth_center.grant_type}")
    public String oauth2GrantType;

    @Value("${business.auth_center.client_id}")
    public String oauth2ClientId;

    @Value("${business.auth_center.client_secret}")
    public String oauth2ClientSecret;

    @Resource
    public TokenStore tokenStore;

    @Autowired
    private SysUserService sysUserService;

    private static final String nullValue= "null";

    /**
     * 注册
     *
     * @param registerRequest {@link RegisterRequest}
     * @return {@link ResponseResult}
     */
    @PostMapping("/register")
    public ResponseResult register(RegisterRequest registerRequest)
    {
        int result = sysUserService.addUser(registerRequest);
        if(result>0)
        {
            return new ResponseResult<>(ResponseResult.CodeStatus.OK, "用户注册成功", null);
        }else {
            return new ResponseResult<>(ResponseResult.CodeStatus.FAIL, "用户注册失败", null);
        }
    }

    @PostMapping("/user/login")
    public ResponseResult<Map<String, Object>> login(@RequestBody LoginRequest loginRequest) {
        // 封装返回的结果集
        Map<String, Object> result = Maps.newHashMap();

        // 通过 HTTP 客户端请求登录接口
        Map<String, String> params = Maps.newHashMap();
        params.put("username", loginRequest.getUsername());
        params.put("password", loginRequest.getPassword());
        params.put("grant_type", oauth2GrantType);
        params.put("client_id", oauth2ClientId);
        params.put("client_secret", oauth2ClientSecret);

        try {
            // 解析响应结果封装并返回
            Response response = OkHttpClientUtil.getInstance().postData(URL_OAUTH_TOKEN, params);
            String jsonString = Objects.requireNonNull(response.body()).string();
            Map<String, Object> jsonMap = JsonUtil.json2map(jsonString);

            String token = String.valueOf(jsonMap.get("access_token"));
            if(token.equals(nullValue)){
                return new ResponseResult<>(ResponseResult.CodeStatus.FAIL, "账号或密码错误", null);
            }
            result.put("token", token);

            // 发送登录日志
            // sendAdminLoginLog(userDetails.getUsername(), request);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return new ResponseResult<>(ResponseResult.CodeStatus.OK, "登录成功", result);
    }

    /**
     * 获取用户信息
     *
     * @return {@link ResponseResult}
     */
    @GetMapping(value = "/user/info")
    public ResponseResult<LoginInfo> info() throws Exception {
        // 获取认证信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        Object principal =SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (principal instanceof UserDetails) {
            String username = ((UserDetails)principal).getUsername();
        } else {
            String username = principal.toString();
        }
//        // 获取个人信息
//        String jsonString = profileFeign.info(authentication.getName());
//        UmsAdmin umsAdmin = MapperUtils.json2pojoByTree(jsonString, "data", UmsAdmin.class);

//        // 如果触发熔断则返回熔断结果
//        if (umsAdmin == null) {
//            return MapperUtils.json2pojo(jsonString, ResponseResult.class);
//        }

        // 封装并返回结果
        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setName(authentication.getName());
        loginInfo.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        loginInfo.setIntroduction("Super Admin");
        List<String> roles = new ArrayList<>();
        roles.add("admin");
        loginInfo.setRoles(roles);
        return new ResponseResult<>(ResponseResult.CodeStatus.OK, "获取用户信息", loginInfo);
    }

    /**
     * 注销
     *
     * @return {@link ResponseResult}
     */
    @PostMapping(value = "/user/logout")
    public ResponseResult<Void> logout(HttpServletRequest request) {
        // 获取 token
        String token = getToken(request);
        // 删除 token 以注销
        OAuth2AccessToken oAuth2AccessToken = tokenStore.readAccessToken(token);
        tokenStore.removeAccessToken(oAuth2AccessToken);
        return new ResponseResult<>(ResponseResult.CodeStatus.OK, "用户已注销");
    }

    private String getToken(HttpServletRequest request){
        String header_authorization = request.getHeader("Authorization");
        String token = (StringUtils.isBlank(header_authorization) ? request.getParameter("access_token") : header_authorization.split(" ")[1]);
    if (StringUtils.isBlank(token) && token == null) {
            throw new RuntimeException("获取Token失败");
        }
        return  token;
    }
}